﻿using InvestmentIntelligence.Data.Repository.Comparers.EntityModelsComparers;
using InvestmentIntelligence.DbModel.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace InvestmentIntelligence.Data.Repository.EFImplementation
{
    using System.Data.Entity;

    public class FundBookSerieRepository : IIPRepository<FundBookEntitySerie>, IFundBookSerieRepository
    {
        public new void BulkInsert(IEnumerable<FundBookEntitySerie> list)
        {
            list = list.Distinct(new FundBookEntitySerieComparer());
            base.BulkInsert(list);
        }

        public List<T> GetList<T>(Func<IQueryable<FundBookEntitySerie>, IEnumerable<T>> f, int fundBookId)
        {
            return
                GetList(
                    dc => f(dc.Where(x => x.FundBookEntityId == fundBookId)));
        }

        public List<FundBookEntitySerie> GetList(Expression<Func<FundBookEntitySerie, bool>> queryExpression)
        {
            return GetList(dc => dc.Where(queryExpression));
        }


        public List<T> GetList<T>(Func<IQueryable<FundBookEntitySerie>, IEnumerable<T>> f, string originalIdentity)
        {
            return GetList(dc => f(dc.Include("FundBookEntity").Where(x => x.FundBookEntity.OriginalId == originalIdentity)));
        }
        
        public DateTime? GetLastDate(int key)
        {
            return Get(v => v.Where(c => c.FundBookEntityId == key).Max(f => (DateTime?)f.Date));
        }

        public Expression<Func<FundBookEntitySerie, bool>> GetQueryExpression(int fundBookId, DateTime? startDate, DateTime? endDate)
        {
            var fundBook = Expression.Parameter(typeof (FundBookEntitySerie), "fundBook");
            var fundBookIdExp = Expression.Property(fundBook, "FundBookEntityId");
            var inputIdExp = Expression.Constant(fundBookId);
            var equalIdExp = Expression.Equal(fundBookIdExp, inputIdExp);
            
            var resultExp = equalIdExp;

            if (startDate.HasValue)
            {
                var fundBookDateExp = Expression.Property(fundBook, "Date");
                var startDateExp = Expression.Constant(startDate.Value);
                var moreThanStartDateExp = Expression.GreaterThanOrEqual(fundBookDateExp, startDateExp);
                resultExp = Expression.AndAlso(resultExp, moreThanStartDateExp);
            }

            if (endDate.HasValue)
            {
                var fundBookDateExp = Expression.Property(fundBook, "Date");
                var endDateExp = Expression.Constant(endDate.Value);
                var lessThanEndDateExp = Expression.LessThanOrEqual(fundBookDateExp, endDateExp);
                resultExp = Expression.AndAlso(resultExp, lessThanEndDateExp);
            }

            var queryExpression = Expression.Lambda<Func<FundBookEntitySerie, bool>>(resultExp, fundBook);
            return queryExpression;
        }
    }
}